package com.shelpe.services.algorithm.autoDrive;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.springframework.stereotype.Service;

import com.shelpe.services.algorithm.client.LexiconClient;
import com.shelpe.services.algorithm.client.LexiconClient.RecommendWordDto;
import com.shelpe.services.algorithm.client.SinbadClient;
import com.shelpe.services.algorithm.entity.jpa.Adgroup;
import com.shelpe.services.algorithm.entity.jpa.AutoProductQueue;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class DefaultRecommendWordFilter implements RecommendWordFilter {

	@Override
	public List<SinbadClient.HandlingKeyword> filter(List<RecommendWordDto> recommends, AutoProductQueue queue, Adgroup adgroup) {
		AutoWordDto maxWord = new AutoWordDto();
		List<AutoWordDto> words = new ArrayList<AutoWordDto>();
		for(LexiconClient.RecommendWordDto rw: recommends){
			AutoWordDto word = new AutoWordDto();
			word.recomend = rw;
			word.score = 0;
			words.add(word);
			maxWord.ctr = Math.max(maxWord.ctr, rw.getClickRatio());
			maxWord.pv = Math.max(maxWord.pv, rw.getImpression());
			maxWord.pertinence = Math.max(maxWord.pertinence, rw.getPertinence());
		}
		maxWord.pv = Math.max(maxWord.pv, 1);
		maxWord.ctr = Math.max(maxWord.ctr, 0.01f);
		log.debug("max: {}", maxWord);
		for(AutoWordDto word: words){
			float score = (((float) word.getRecomend().getClickRatio()) / maxWord.ctr) * 50;
			score = score + (((float) word.getRecomend().getImpression()) / maxWord.pv) * 45;
			score = score + (((float) word.getRecomend().getPertinence()) / maxWord.pertinence) * 5;
			word.score = (int) score;
			log.debug("word {} score: ", word.getRecomend().getWord(), word.getScore());
		}
		
		Collections.sort(words, new Comparator<AutoWordDto>(){
			@Override
			public int compare(AutoWordDto o1, AutoWordDto o2) {
				return o2.getScore() - o1.getScore();
			}
		});
		
		List<SinbadClient.HandlingKeyword> handlingWords = new ArrayList<SinbadClient.HandlingKeyword>();
		for (AutoWordDto word : words) {
			log.debug("check word: {}", word);
			SinbadClient.HandlingKeyword keyword = new SinbadClient.HandlingKeyword();
			keyword.setWord(word.getRecomend().getWord());
			int price = (int) (word.getRecomend().getPrice() * 100);
			if(price == 0){
				price = (int) (word.getRecomend().getRecommendPrice() * 100);
			}
			if(price == 0){
				price = adgroup.getLimit() / 5;
			}
			
			if(adgroup.getLimit() > 0 && price > adgroup.getLimit()){
				price = adgroup.getLimit();
			}
			
			keyword.setMaxPrice(price);
			keyword.setMatchScope(4);
			keyword.setIsDefaultPrice(0);
			if(keyword.getMaxPrice() >= 5 && word.getRecomend().isCenteral()){
				handlingWords.add(keyword);
			}else{
				log.debug("not add as keyword as price: {} {}", keyword.getWord(), keyword.getMaxPrice());
			}
		}
		return handlingWords;
	}

	
	@Data
	public static class AutoWordDto{
		private LexiconClient.RecommendWordDto recomend;
		private int pv;
		private int score;
		private float ctr;
		private int pertinence;
	}


	@Override
	public boolean support(Adgroup adgroup, AutoProductQueue queue) {
		boolean isDriver = false;
		if(adgroup != null){
			isDriver = adgroup.getDriveType() == 1;
		}else if(queue != null){
			isDriver = queue.getFlag() == 0;
		}
		return isDriver;
	}
}
